package com.design.framework.utils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Base64;
import java.util.Map;

import org.springframework.web.multipart.MultipartFile;

import com.design.framework.exception.bean.CustomException;
import com.obs.services.ObsClient;
import com.obs.services.model.HttpMethodEnum;
import com.obs.services.model.ObsObject;
import com.obs.services.model.PutObjectResult;
import com.obs.services.model.TemporarySignatureRequest;
import com.obs.services.model.TemporarySignatureResponse;

/**
 * 华为云图片工具类
 *
 * @author JohnDeng
 * @datetime 2019年9月26日下午3:49:16
 */
public class HuaWeiYunObsUtils {

  private String accessKey;
  private String secretKey;
  private String endPoint;

  public HuaWeiYunObsUtils(String accessKey, String secretKey, String endPoint) {
    this.accessKey = accessKey;
    this.secretKey = secretKey;
    this.endPoint = endPoint;
  }

  public HuaWeiYunObsUtils(Map<String, String> map) {
    this.accessKey = map.get("accessKey").toString();
    this.secretKey = map.get("secretKey").toString();
    this.endPoint = map.get("endPoint").toString();
  }

  /**
   * 初始化
   *
   * @return
   * @author JohnDeng
   * @datetime 2019年8月6日上午10:21:43
   */
  private ObsClient init(String accessKey, String secretKey, String endPoint) {
    ObsClient obsClient = new ObsClient(accessKey, secretKey, endPoint);
    return obsClient;
  }

  /**
   * 销毁
   *
   * @param obsClient
   * @author JohnDeng
   * @datetime 2019年8月6日上午10:21:50
   */
  private void destroy(ObsClient obsClient) {
    if (obsClient != null) {
      try {
        obsClient.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 上传字符串
   *
   * @param content    字符串
   * @param objectName 对象名称
   * @author JohnDeng
   * @datetime 2019年8月6日上午10:04:41
   */
  public PutObjectResult uploadString(String content, String objectName, String bucketname) throws IOException {
    ObsClient obsClient = init(accessKey, secretKey, endPoint);
    byte[] bytes = Base64.getDecoder().decode(content);
    PutObjectResult result = obsClient.putObject(bucketname, objectName, new ByteArrayInputStream(bytes));
    destroy(obsClient);
    return result;
  }

  /**
   * 上传网络流
   *
   * @param url        url链接
   * @param objectName 对象名称
   * @author JohnDeng
   * @datetime 2019年8月6日上午10:23:50
   */
  public PutObjectResult uploadNetworkUrl(String url, String objectName, String bucketname) {
    ObsClient obsClient = init(accessKey, secretKey, endPoint);
    PutObjectResult result = null;
    try {
      InputStream inputStream = new URL(url).openStream();
      result = obsClient.putObject(bucketname, objectName, inputStream);
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    destroy(obsClient);
    return result;
  }

  /**
   * 文件上传
   *
   * @param localfile  上传的本地文件路径，需要指定到具体的文件名
   * @param objectName 对象名称
   * @author JohnDeng
   * @datetime 2019年8月6日上午10:29:20
   */
  public PutObjectResult uploadFileInputStream(String localfile, String objectName, String bucketname) {
    ObsClient obsClient = init(accessKey, secretKey, endPoint);
    // localfile为待上传的本地文件路径，需要指定到具体的文件名
    PutObjectResult result = obsClient
        .putObject(bucketname, objectName, new File(localfile));
    destroy(obsClient);
    return result;
  }

  /**
   * 流式下载
   *
   * @param objectname
   * @return
   * @author JohnDeng
   * @datetime 2019年8月6日上午11:07:46
   */
  public InputStream downloadStream(String objectname, String accessKey, String secretKey, String endPoint,
      String bucketname) {
    final ObsClient obsClient = init(accessKey, secretKey, endPoint);
    InputStream input = null;
    try {
      ObsObject obsObject = obsClient.getObject(bucketname, objectname);
      input = obsObject.getObjectContent();
    } catch (Exception e) {
      e.printStackTrace();
    }finally {
      try {
        if(input!=null){
          input.close();
        }
      }catch (IOException e){
          e.printStackTrace();
      }
    }
    return input;
  }

  /**
   * @description: 图片回显 @author ljj @date 2019/9/9 17:15
   */
  public String picDownload(String objectname, String bucketname) throws Exception {
    String httpCode = "443";
    if (StringUtils.isEmpty(objectname)) {
      return objectname;
    }
    // 初始化
    ObsClient obsClient = this.init(accessKey, secretKey, endPoint);
    long expireSeconds = 3600L;
    // 截取图片路径
    String replaceAll = objectname.replaceAll("https://", "");
    String path = replaceAll.substring(replaceAll.indexOf("/") + 1, replaceAll.length());
    String pathHost = path;
    if (!objectname.contains(httpCode)) {
      pathHost = path.substring(path.indexOf("/") + 1, path.length());
    }
    // 下载图片
    try {
      TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
      request.setBucketName(bucketname);
      request.setObjectKey(pathHost);
      TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
      return response.getSignedUrl();
    } catch (Exception e) {
      throw new CustomException("400", "华为云URL访问授权失败");
    }
  }

  /**
   * @description: 上传图片 @author ljj @date 2019/9/9 17:41
   */
  public String uploadImg(MultipartFile file, String path, String bucketname) throws Exception {
    String timestamp = String.valueOf(System.currentTimeMillis());
    String base64 = new String(Base64.getEncoder().encode(file.getBytes()));
    String fileName = path + timestamp + "_" + file.getOriginalFilename();
    PutObjectResult result = uploadString(base64, fileName, bucketname);
    String picUrl = URLDecoder.decode(result.getObjectUrl(), "utf-8");
    return picUrl;
  }
}
